home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-19 / iritsm3s.zip / OBJECTS.C < prev    next >
C/C++ Source or Header  |  1992-02-23  |  23KB  |  695 lines

  1. /*****************************************************************************
  2. *   "Irit" - the 3d polygonal solid modeller.                     *
  3. *                                         *
  4. * Written by:  Gershon Elber                Ver 0.2, Mar. 1990   *
  5. ******************************************************************************
  6. *   Module to handle the objects list - fetch, insert, delete etc...         *
  7. *****************************************************************************/
  8.  
  9. /* #define DEBUG               Output goes to stdout if defined. */
  10.  
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <math.h>
  14. #include "program.h"
  15. #include "allocate.h"
  16. #include "dataprsr.h"
  17. #include "attribut.h"
  18. #include "geomat3d.h"
  19. #include "graphgen.h"
  20. #include "objects.h"
  21. #include "windows.h"
  22.  
  23. static int GetDumpLevel(void);
  24. static PolygonStruct *GenAxesObjectPolylines(void);
  25. static void PrintOneLine(char *Line);
  26.  
  27. /*****************************************************************************
  28. *   Routine to set up all the predefined objects - objects that the system   *
  29. * must have all the time, like global transformation matrix.             *
  30. *****************************************************************************/
  31. void SetUpPredefObjects(void)
  32. {
  33.     RealType R;
  34.     MatrixType Mat1, Mat2;
  35.     ObjectStruct *PObj;
  36.  
  37.     /* 90 - 35.2644 = 54.7356 */
  38.     MatGenMatRotX1(DEG2RAD(-54.7356), Mat1); /* Generate default view trans. */
  39.     MatGenMatRotZ1(M_PI+M_PI/4, Mat2);         /* which is isometric view. */
  40.     MatMultTwo4by4(Mat2, Mat2, Mat1);
  41.     PObj = GenMatObject("VIEW_MAT", Mat2, NULL);
  42.     InsertObject(PObj);
  43.  
  44.     MatGenUnitMat(Mat1);          /* Generate default perspective trans. */
  45.     Mat1[2][2] = 0.1;
  46.     Mat1[2][3] = -0.35;
  47.     Mat1[3][2] = 0.35;
  48.     PObj = GenMatObject("PRSP_MAT", Mat1, NULL);
  49.     InsertObject(PObj);
  50.  
  51.     R = DEFAULT_RESOLUTION;
  52.     PObj = GenNumObject("RESOLUTION", &R, NULL);
  53.     InsertObject(PObj);
  54.  
  55.     R = DEFAULT_DRAW_CTLPT;
  56.     PObj = GenNumObject("DRAWCTLPT", &R, NULL);
  57.     InsertObject(PObj);
  58.  
  59.     R = DEFAULT_INTERNAL;
  60.     PObj = GenNumObject("INTERNAL", &R, NULL);
  61.     InsertObject(PObj);
  62.  
  63.     R = DEFAULT_INTERCRV;
  64.     PObj = GenNumObject("INTERCRV", &R, NULL);
  65.     InsertObject(PObj);
  66.  
  67.     R = DEFAULT_ECHOSRC;
  68.     PObj = GenNumObject("ECHOSRC", &R, NULL);
  69.     InsertObject(PObj);
  70.  
  71.     R = DEFAULT_DUMPLVL;
  72.     PObj = GenNumObject("DUMPLVL", &R, NULL);
  73.     InsertObject(PObj);
  74.  
  75.     R = 0;
  76.     PObj = GenNumObject("FLAT4PLY", &R, NULL);
  77.     InsertObject(PObj);
  78.  
  79.     R = MACHINE_UNIX;
  80. #if defined(__MSDOS__) || defined(DJGCC)
  81.     R = MACHINE_MSDOS;
  82. #endif
  83. #if defined(sgi)
  84.     R = MACHINE_SGI;
  85. #endif
  86. #if defined(hpbsd) || defined(hpux)
  87.     R = MACHINE_HP;
  88. #endif
  89. #if defined(sun)
  90.     R = MACHINE_SUN;
  91. #endif
  92. #if defined(apollo)
  93.     R = MACHINE_APOLLO;
  94. #endif
  95.  
  96.     PObj = GenNumObject("MACHINE", &R, NULL);
  97.     InsertObject(PObj);
  98.  
  99.     PObj = GenPolyObject("AXES", GenAxesObjectPolylines(), NULL);
  100.     SET_POLYLINE_OBJ(PObj);              /* Mark it as polyline object. */
  101.     InsertObject(PObj);
  102. }
  103.  
  104. /*****************************************************************************
  105. *   Routine to get the value to EchoSrc variable.                 *
  106. *****************************************************************************/
  107. static int GetDumpLevel(void)
  108. {
  109.     int DumpLvl;
  110.     ObjectStruct
  111.     *PObj = GetObject("DUMPLVL");
  112.  
  113.     if (PObj == NULL || !IS_NUM_OBJ(PObj)) {
  114.     WndwInputWindowPutStr("No numeric object name DumpLvl is defined");
  115.     DumpLvl = DEFAULT_DUMPLVL;
  116.     }
  117.     else
  118.     DumpLvl = (int) (PObj -> U.R);
  119.  
  120.     return DumpLvl;
  121. }
  122.  
  123. /*****************************************************************************
  124. *   Generate an axes system with length of 1 on each axis.             *
  125. *****************************************************************************/
  126. static PolygonStruct *GenAxesObjectPolylines(void)
  127. {
  128.     PolygonStruct *Pl, *PlHead;
  129.     VertexStruct *V;
  130.  
  131.     Pl = PlHead = AllocPolygon(0, 0, NULL, NULL);          /* X axis. */
  132.     Pl -> V = V = AllocVertex(0, 0, NULL, NULL);
  133.     V -> Pt[0] = 0.0;    V -> Pt[1] = 0.0;   V -> Pt[2] = 0.0;
  134.     V -> Pnext = AllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
  135.     V -> Pt[0] = 1.0;    V -> Pt[1] = 0.0;   V -> Pt[2] = 0.0;
  136.     V -> Pnext = AllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
  137.     V -> Pt[0] = 1.0;    V -> Pt[1] = 0.1;   V -> Pt[2] = 0.1;
  138.  
  139.     Pl -> Pnext = AllocPolygon(0, 0, NULL, NULL); Pl = Pl -> Pnext;
  140.     Pl -> V = V = AllocVertex(0, 0, NULL, NULL);
  141.     V -> Pt[0] = 1.0;    V -> Pt[1] = 0.1;   V -> Pt[2] = 0.0;
  142.     V -> Pnext = AllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
  143.     V -> Pt[0] = 1.0;    V -> Pt[1] = 0.0;   V -> Pt[2] = 0.1;
  144.  
  145.     Pl -> Pnext = AllocPolygon(0, 0, NULL, NULL); Pl = Pl -> Pnext;/* Y axis.*/
  146.     Pl -> V = V = AllocVertex(0, 0, NULL, NULL);
  147.     V -> Pt[0] = 0.0;    V -> Pt[1] = 0.0;   V -> Pt[2] = 0.0;
  148.     V -> Pnext = AllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
  149.     V -> Pt[0] = 0.0;    V -> Pt[1] = 1.0;   V -> Pt[2] = 0.0;
  150.     V -> Pnext = AllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
  151.     V -> Pt[0] = 0.0;    V -> Pt[1] = 1.0;   V -> Pt[2] = 0.06;
  152.     V -> Pnext = AllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
  153.     V -> Pt[0] = 0.04;    V -> Pt[1] = 1.0;   V -> Pt[2] = 0.1;
  154.     V -> Pnext = AllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
  155.     V -> Pt[0] = 0.0;    V -> Pt[1] = 1.0;   V -> Pt[2] = 0.06;
  156.     V -> Pnext = AllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
  157.     V -> Pt[0] =(-0.04);V -> Pt[1] = 1.0;   V -> Pt[2] = 0.1;
  158.  
  159.     Pl -> Pnext = AllocPolygon(0, 0, NULL, NULL); Pl = Pl -> Pnext;/* Z axis.*/
  160.     Pl -> V = V = AllocVertex(0, 0, NULL, NULL);
  161.     V -> Pt[0] = 0.0;    V -> Pt[1] = 0.0;   V -> Pt[2] = 0.0;
  162.     V -> Pnext = AllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
  163.     V -> Pt[0] = 0.0;    V -> Pt[1] = 0.0;   V -> Pt[2] = 1.0;
  164.     V -> Pnext = AllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
  165.     V -> Pt[0] = 0.1;    V -> Pt[1] = 0.0;   V -> Pt[2] = 1.0;
  166.     V -> Pnext = AllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
  167.     V -> Pt[0] = 0.0;    V -> Pt[1] = 0.1;   V -> Pt[2] = 1.0;
  168.     V -> Pnext = AllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
  169.     V -> Pt[0] = 0.1;    V -> Pt[1] = 0.1;   V -> Pt[2] = 1.0;
  170.  
  171.     return PlHead;
  172. }
  173.  
  174. /*****************************************************************************
  175. *   Get the nth object in a list. Object reference is properly updated.      *
  176. *****************************************************************************/
  177. ObjectStruct *GetNthList(ObjectStruct *ListObj, RealType *Rn)
  178. {
  179.     int i,
  180.     n = REAL_PTR_TO_INT(Rn);
  181.     ObjectStruct *PObj;
  182.  
  183.     if (!IS_OLST_OBJ(ListObj)) {
  184.     WndwInputWindowPutStr("None list object ignored.");
  185.         return NULL;
  186.     }
  187.  
  188.     if (n < 1 || n >= MAX_OBJ_LIST) {
  189.     WndwInputWindowPutStr("Out of range of list.");
  190.         return NULL;
  191.     }
  192.     for (i = 0; i < n; i++) if (ListObj -> U.PObjList[i] == NULL) {
  193.     WndwInputWindowPutStr("Out of range of list.");
  194.         return NULL;
  195.     }
  196.  
  197.     PObj = CopyObject(NULL, ListObj -> U.PObjList[n - 1], FALSE);
  198.     return PObj;
  199. }
  200.  
  201. /*****************************************************************************
  202. *  Append two lists. Object reference is properly updated.             *
  203. *****************************************************************************/
  204. ObjectStruct *AppendLists(ObjectStruct *ListObj1, ObjectStruct *ListObj2)
  205. {
  206.     int i, j;
  207.     ObjectStruct *PObj;
  208.  
  209.     if (!IS_OLST_OBJ(ListObj1) && !IS_OLST_OBJ(ListObj2)) {
  210.     WndwInputWindowPutStr("None list object ignored.");
  211.     return NULL;
  212.     }
  213.  
  214.     PObj = AllocObject("", OBJ_LIST_OBJ, NULL);
  215.  
  216.     for (i = 0; ListObj1 -> U.PObjList[i] != NULL && i < MAX_OBJ_LIST; i++) {
  217.     PObj -> U.PObjList[i] = ListObj1 -> U.PObjList[i];
  218.     PObj -> U.PObjList[i] -> Count++;
  219.     }
  220.  
  221.     for (j = 0; ListObj2 -> U.PObjList[j] != NULL && i < MAX_OBJ_LIST; i++, j++) {
  222.     PObj -> U.PObjList[i] = ListObj2 -> U.PObjList[j];
  223.     PObj -> U.PObjList[i] -> Count++;
  224.     }
  225.     if (i < MAX_OBJ_LIST)
  226.     PObj -> U.PObjList[i] = NULL;
  227.  
  228.     return PObj;
  229. }
  230.  
  231. /*****************************************************************************
  232. *  Snoc (Cons to the end of the list, in place) the object to the list in    *
  233. * the second argument.                                 *
  234. *****************************************************************************/
  235. void SnocList(ObjectStruct *PObj, ObjectStruct *ListObj)
  236. {
  237.     int i;
  238.  
  239.     if (!IS_OLST_OBJ(ListObj)) {
  240.     WndwInputWindowPutStr("None list object ignored.");
  241.     return;
  242.     }
  243.  
  244.     for (i = 0; ListObj -> U.PObjList[i] != NULL && i < MAX_OBJ_LIST - 2; i++);
  245.     if (i < MAX_OBJ_LIST - 2) {
  246.     ListObj -> U.PObjList[i] = CopyObject(NULL, PObj, FALSE);
  247.     ListObj -> U.PObjList[i] -> Count = 1;
  248.     ListObj -> U.PObjList[i + 1] = NULL;
  249.     }
  250. }
  251.  
  252. /*****************************************************************************
  253. *   Get object by its name - scans the object linear list.             *
  254. * Note the termination is also on 1000 objects (simple debugging aid in case *
  255. * the Object list became circular), and a fatal error is produced.         *
  256. *****************************************************************************/
  257. ObjectStruct *GetObject(char *ObjName)
  258. {
  259.     int i = 0;
  260.     ObjectStruct
  261.     *PObj = GlblObjList;
  262.  
  263.     while (PObj) {
  264.     if (strcmp(PObj -> Name, ObjName) == 0) {
  265.         return PObj;
  266.     }
  267.     PObj = PObj -> Pnext;
  268.     if (i++ >= 1000)
  269.         FatalError("GetObject: Global Object list too big (>1000)\n");
  270.     }
  271.     return NULL;
  272. }
  273.  
  274. /*****************************************************************************
  275. *   Free Object - delete it from global active list and free all it memory   *
  276. *****************************************************************************/
  277. void FreeObject(ObjectStruct *PObj)
  278. {
  279.     /* Force free the object. Since the reference count should be actually   */
  280.     /* two (second for the parsing tree reference) we decrement it here.     */
  281.     if (PObj->Count == 2)
  282.     {
  283.     PObj->Count = 1;
  284.     DeleteObject(PObj, TRUE);
  285.     }
  286.     else
  287.     {
  288.     /* Reduce the reference count by two - one for the parsing tree      */
  289.     /* this routine was called from and one for the fact this object     */
  290.     /* reference count is to be deleted since this routine was called.   */
  291.     DeleteObject(PObj, FALSE);
  292.     PObj->Count -= 2;
  293.     }
  294. }
  295.  
  296. /*****************************************************************************
  297. *   Delete object by its pointer - scans the object linear list.         *
  298. * Note the deleted record is free only if Free = TRUE.                 *
  299. *****************************************************************************/
  300. void DeleteObject(ObjectStruct *PObj, int Free)
  301. {
  302.     ObjectStruct
  303.     *PObjScan = GlblObjList;
  304.  
  305.     if (GlblObjList == NULL) return;
  306.  
  307.     if (PObj == GlblObjList) {       /* If it is the first one - special case. */
  308.     GlblObjList = GlblObjList->Pnext;
  309.     if (Free) MyFree((char *) PObj, ALLOC_OBJECT);
  310.     return;
  311.     }
  312.  
  313.     while (PObjScan->Pnext) {
  314.     if (PObj == PObjScan->Pnext) {
  315.         PObjScan->Pnext = PObjScan->Pnext->Pnext;/* Delete it from list. */
  316.         if (Free) MyFree((char *) PObj, ALLOC_OBJECT);   /* And free it. */
  317.         return;
  318.     }
  319.     PObjScan = PObjScan->Pnext;
  320.     }
  321. }
  322.  
  323. /*****************************************************************************
  324. *   Insert object by its pointer - as first in object linear list.         *
  325. * Note it is assumed the object is not in the object list allready.         *
  326. *****************************************************************************/
  327. void InsertObject(ObjectStruct *PObj)
  328. {
  329.     PObj -> Pnext = GlblObjList;
  330.     GlblObjList = PObj;
  331. }
  332.  
  333. /*****************************************************************************
  334. *   Print one line.                                 *
  335. *****************************************************************************/
  336. static void PrintOneLine(char *Line)
  337. {
  338.     WndwInputWindowPutStr(Line);
  339. }
  340.  
  341. /*****************************************************************************
  342. *   Print some usefull info on the given object.                 *
  343. *****************************************************************************/
  344. void PrintObject(ObjectStruct *PObj)
  345. {
  346.     int Count = PObj -> Count;
  347.     CagdRType
  348.     DumpLvl = GetDumpLevel();
  349.     char Line[LINE_LEN_LONG],
  350.     *Name = (int) strlen(PObj -> Name) > 0 ? PObj -> Name : "NONE";
  351.  
  352.     switch (PObj->ObjType) {
  353.     case UNDEF_OBJ:
  354.         sprintf(Line, "%-10s (%d) - Undefined type", Name, Count);
  355.         PrintOneLine(Line);
  356.         break;
  357.     case POLY_OBJ:
  358.         sprintf(Line, "%-10s (%d) - Poly      type", Name, Count);
  359.         PrintOneLine(Line);
  360.         if (DumpLvl >= 3)
  361.         DataPrsrPutObject(NULL, PObj);
  362.         break;
  363.     case NUMERIC_OBJ:
  364.         sprintf(Line, "%-10s (%d) - Numeric   type", Name, Count);
  365.         PrintOneLine(Line);
  366.         if (DumpLvl >= 1)
  367.         DataPrsrPutObject(NULL, PObj);
  368.         break;
  369.     case VECTOR_OBJ:
  370.         sprintf(Line, "%-10s (%d) - Vector    type", Name, Count);
  371.         PrintOneLine(Line);
  372.         if (DumpLvl >= 1)
  373.         DataPrsrPutObject(NULL, PObj);
  374.         break;
  375.     case CTLPT_OBJ:
  376.         sprintf(Line, "%-10s (%d) - CtlPt     type", Name, Count);
  377.         PrintOneLine(Line);
  378.         if (DumpLvl >= 1)
  379.         DataPrsrPutObject(NULL, PObj);
  380.         break;
  381.     case MATRIX_OBJ:
  382.         sprintf(Line, "%-10s (%d) - Matrix    type", Name, Count);
  383.         PrintOneLine(Line);
  384.         if (DumpLvl >= 1)
  385.         DataPrsrPutObject(NULL, PObj);
  386.         break;
  387.     case STRING_OBJ:
  388.         sprintf(Line, "%-10s (%d) - String    type", Name, Count);
  389.         PrintOneLine(Line);
  390.         if (DumpLvl >= 1)
  391.         DataPrsrPutObject(NULL, PObj);
  392.         break;
  393.     case OBJ_LIST_OBJ:
  394.         sprintf(Line, "%-10s (%d) - Object List type", Name, Count);
  395.         PrintOneLine(Line);
  396.         if (DumpLvl >= 4)
  397.         DataPrsrPutObject(NULL, PObj);
  398.         break;
  399.     case CURVE_OBJ:
  400.         sprintf(Line, "%-10s (%d) - Curve     type", Name, Count);
  401.         PrintOneLine(Line);
  402.         if (DumpLvl >= 2) {
  403.         CagdSetCagdFprintf(PrintOneLine);
  404.         DataPrsrPutObject(NULL, PObj);
  405.         CagdSetCagdFprintf(NULL);
  406.         }
  407.         break;
  408.     case SURFACE_OBJ:
  409.         sprintf(Line, "%-10s (%d) - Surface   type", Name, Count);
  410.         PrintOneLine(Line);
  411.         if (DumpLvl >= 2) {
  412.         CagdSetCagdFprintf(PrintOneLine);
  413.         DataPrsrPutObject(NULL, PObj);
  414.         CagdSetCagdFprintf(NULL);
  415.         }
  416.         break;
  417.     default:
  418.         sprintf(Line, "%-10s (%d) - Obj type error, type = %d",
  419.                 Name, Count, PObj->ObjType);
  420.         PrintOneLine(Line);
  421.         break;
  422.     }
  423. }
  424.  
  425. /*****************************************************************************
  426. *   Print some usefull info on all the given objects.                 *
  427. *****************************************************************************/
  428. void PrintObjectList(ObjectStruct *PObj)
  429. {
  430.     PrintOneLine("");
  431.  
  432.     while (PObj != NULL) {
  433.     PrintObject(PObj);
  434.     PObj = PObj -> Pnext;
  435.     }
  436. }
  437.  
  438. /*****************************************************************************
  439. *   Generate one polygonal object:                         *
  440. *****************************************************************************/
  441. ObjectStruct *GenPolyObject(char *Name, PolygonStruct *Pl, ObjectStruct *Pnext)
  442. {
  443.     ObjectStruct *PObj;
  444.  
  445.     PObj = AllocObject(Name, POLY_OBJ, Pnext);
  446.     ResetObjectAttribs(PObj);               /* Initialize attributes. */
  447.     RST_POLYLINE_OBJ(PObj);           /* Default - not polyline object. */
  448.  
  449.     PObj -> U.Pl.P = Pl;             /* Link the union part of it... */
  450.  
  451.     return PObj;
  452. }
  453.  
  454. /*****************************************************************************
  455. *   Generate one curve object:                             *
  456. *****************************************************************************/
  457. ObjectStruct *GenCrvObject(char *Name, CagdCrvStruct *Crv, ObjectStruct *Pnext)
  458. {
  459.     ObjectStruct *PObj;
  460.  
  461.     PObj = AllocObject(Name, CURVE_OBJ, Pnext);
  462.     ResetObjectAttribs(PObj);               /* Initialize attributes. */
  463.  
  464.     PObj -> U.Crv.Crv = Crv;             /* Link the union part of it... */
  465.     PObj -> U.Crv.PLPolys = NULL;
  466.     PObj -> U.Crv.CtlPoly = NULL;
  467.  
  468.     return PObj;
  469. }
  470.  
  471. /*****************************************************************************
  472. *   Generate one surface object:                         *
  473. *****************************************************************************/
  474. ObjectStruct *GenSrfObject(char *Name, CagdSrfStruct *Srf, ObjectStruct *Pnext)
  475. {
  476.     ObjectStruct *PObj;
  477.  
  478.     PObj = AllocObject(Name, SURFACE_OBJ, Pnext);
  479.     ResetObjectAttribs(PObj);               /* Initialize attributes. */
  480.  
  481.     PObj -> U.Srf.Srf = Srf;             /* Link the union part of it... */
  482.     PObj -> U.Srf.PLPolys = NULL;
  483.     PObj -> U.Srf.CtlMesh = NULL;
  484.     PObj -> U.Srf.Polygons = NULL;
  485.  
  486.     return PObj;
  487. }
  488.  
  489. /*****************************************************************************
  490. *   Generate one control point object:                         *
  491. *   Only one of CagdCoords/Coords should be specified.                 *
  492. *****************************************************************************/
  493. ObjectStruct *GenCtlPtObject(char *Name, CagdPointType PtType,
  494.         CagdRType *CagdCoords, RealType *Coords, ObjectStruct *Pnext)
  495. {
  496.     int i;
  497.     CagdBType
  498.     IsNotRational = !CAGD_IS_RATIONAL_PT(PtType);
  499.     ObjectStruct *PObj;
  500.     RealType *t;
  501.  
  502.     PObj = AllocObject(Name, CTLPT_OBJ, Pnext);
  503.     PObj -> U.CtlPt.PtType = PtType;
  504.     t = PObj -> U.CtlPt.Coords;
  505.  
  506.     if (CagdCoords != NULL)
  507.     for (i = IsNotRational;
  508.          i <= CAGD_NUM_OF_PT_COORD(PtType);
  509.          i++) t[i] = CagdCoords[i];
  510.     else
  511.     for (i = IsNotRational;
  512.          i <= CAGD_NUM_OF_PT_COORD(PtType);
  513.          i++) t[i] = Coords[i];
  514.  
  515.     return PObj;
  516. }
  517.  
  518. /*****************************************************************************
  519. *   Generate one numeric object:                         *
  520. *****************************************************************************/
  521. ObjectStruct *GenNumObject(char *Name, RealType *R, ObjectStruct *Pnext)
  522. {
  523.     ObjectStruct *PObj;
  524.  
  525.     PObj = AllocObject(Name, NUMERIC_OBJ, Pnext);
  526.  
  527.     PObj -> U.R = *R;                 /* Link the union part of it... */
  528.  
  529.     return PObj;
  530. }
  531.  
  532. /*****************************************************************************
  533. *   Generate one vector object:                             *
  534. *****************************************************************************/
  535. ObjectStruct *GenVecObject(char *Name, RealType *Vec0, RealType *Vec1,
  536.                     RealType *Vec2, ObjectStruct *Pnext)
  537. {
  538.     ObjectStruct *PObj;
  539.  
  540.     PObj = AllocObject(Name, VECTOR_OBJ, Pnext);
  541.  
  542.     PObj -> U.Vec[0] = *Vec0;             /* Link the union part of it... */
  543.     PObj -> U.Vec[1] = *Vec1;
  544.     PObj -> U.Vec[2] = *Vec2;
  545.  
  546.     return PObj;
  547. }
  548.  
  549. /*****************************************************************************
  550. *   Generate one matrix object:                             *
  551. *****************************************************************************/
  552. ObjectStruct *GenMatObject(char *Name, MatrixType Mat, ObjectStruct *Pnext)
  553. {
  554.     int i, j;
  555.     ObjectStruct *PObj;
  556.  
  557.     PObj = AllocObject(Name, MATRIX_OBJ, Pnext);
  558.  
  559.     for (i = 0; i < 4; i++)             /* Link the union part of it... */
  560.     for (j = 0; j < 4; j++) PObj -> U.Mat[i][j] = Mat[i][j];
  561.  
  562.     return PObj;
  563. }
  564.  
  565. /*****************************************************************************
  566. *   Routine to create a whole new copy of an object Src into Dest.         *
  567. * if Dest is NULL, new object is allocated, otherwise Dest itself is updated *
  568. * If CopyAll then all the record is copied, otherwise, only its variant      *
  569. * element (i.e. no Name/Pnext coping) is been copied.                 *
  570. *****************************************************************************/
  571. ObjectStruct *CopyObject(ObjectStruct *Dest, ObjectStruct *Src, int CopyAll)
  572. {
  573.     int index;
  574.     char Line[LINE_LEN];
  575.  
  576.     if (Dest == NULL)
  577.     Dest = AllocObject("", Src->ObjType, NULL);
  578.     else {
  579.     Dest->ObjType = Src->ObjType;
  580.     }
  581.  
  582.     if (Dest == Src) return Dest;    /* Called with same object - ignore. */
  583.  
  584.     if (CopyAll) {
  585.     strcpy(Dest->Name, Src->Name);
  586.     Dest->Pnext = Src->Pnext;     /* Maybe assigning NULL is better!? */
  587.     }
  588.  
  589.     switch (Src->ObjType) {
  590.     case POLY_OBJ:
  591.         Dest->U.Pl.P = CopyPolygonList(Src->U.Pl.P);
  592.         CopyGeomAttrib(Dest, Src);
  593.         Dest->U.Pl.IsPolyline = Src->U.Pl.IsPolyline;
  594.         break;
  595.     case NUMERIC_OBJ:
  596.         Dest->U.R = Src->U.R;
  597.         break;
  598.     case VECTOR_OBJ:
  599.         PT_COPY(Dest->U.Vec, Src->U.Vec);
  600.         break;
  601.     case CTLPT_OBJ:
  602.         GEN_COPY(&Dest->U.CtlPt, &Src->U.CtlPt,
  603.              CAGD_MAX_PT_SIZE * sizeof(RealType));
  604.         break;
  605.     case MATRIX_OBJ:
  606.         MAT_COPY(Dest->U.Mat, Src->U.Mat);
  607.         break;
  608.     case STRING_OBJ:
  609.         strcpy(Dest->U.Str, Src->U.Str);
  610.         break;
  611.     case OBJ_LIST_OBJ:
  612.         GEN_COPY(Dest->U.PObjList, Src->U.PObjList,
  613.             MAX_OBJ_LIST * sizeof(ObjectStruct *));
  614.         index = 0;
  615.         while (index < MAX_OBJ_LIST &&
  616.            Dest -> U.PObjList[index] != NULL)
  617.         Dest -> U.PObjList[index++] -> Count++;    /* Inc. # of ref. */
  618.         break;
  619.     case CURVE_OBJ:
  620.         Dest->U.Crv.Crv = CagdCrvCopy(Src->U.Crv.Crv);
  621.         Dest->U.Crv.PLPolys = NULL;
  622.         Dest->U.Crv.CtlPoly = NULL;
  623.         CopyGeomAttrib(Dest, Src);
  624.         break;
  625.     case SURFACE_OBJ:
  626.         Dest->U.Srf.Srf = CagdSrfCopy(Src->U.Srf.Srf);
  627.         Dest->U.Srf.PLPolys = NULL;
  628.         Dest->U.Srf.CtlMesh = NULL;
  629.         Dest->U.Srf.Polygons = NULL;
  630.         CopyGeomAttrib(Dest, Src);
  631.         break;
  632.     default:
  633.         sprintf(Line,
  634.         "CopyObject Attemp to copy undefined object %s type %d\n",
  635.         Src->Name, Src->ObjType);
  636.         FatalError(Line);
  637.     }
  638.     return Dest;
  639. }
  640.  
  641. /*****************************************************************************
  642. *   Routine to generate a new copy of an object polygon list.             *
  643. *****************************************************************************/
  644. PolygonStruct *CopyPolygonList(PolygonStruct *Src)
  645. {
  646.     PolygonStruct *Phead, *Ptail;
  647.  
  648.     if (Src == NULL) return NULL;
  649.  
  650.     /* Prepare the header of the new polygon list: */
  651.     Phead = Ptail = AllocPolygon(1, Src->Tags, CopyVList(Src->V), NULL);
  652.     PLANE_COPY(Ptail -> Plane, Src -> Plane);
  653.     Src = Src -> Pnext;
  654.  
  655.     while (Src != NULL) {
  656.     Ptail -> Pnext = AllocPolygon(Src->Count, Src->Tags,
  657.                         CopyVList(Src->V), NULL);
  658.     Ptail = Ptail -> Pnext;
  659.     PLANE_COPY(Ptail -> Plane, Src -> Plane);
  660.     Src = Src -> Pnext;
  661.     }
  662.  
  663.     return Phead;
  664. }
  665.  
  666. /*****************************************************************************
  667. *   Routine to generate a new copy of a polygon vertices list.             *
  668. *****************************************************************************/
  669. VertexStruct *CopyVList(VertexStruct *Src)
  670. {
  671.     VertexStruct *Phead, *Ptail,
  672.     *SrcFirst = Src;
  673.  
  674.     if (Src == NULL) return NULL;
  675.  
  676.     /* Prepare the header of the new vertex list: */
  677.     Phead = Ptail = AllocVertex(Src -> Count, Src -> Tags, NULL, NULL);
  678.     PT_COPY(Phead -> Pt, Src -> Pt);
  679.     PT_COPY(Phead -> Normal, Src -> Normal);
  680.     Src = Src -> Pnext;
  681.  
  682.     while (Src != SrcFirst && Src != NULL) {
  683.     Ptail -> Pnext = AllocVertex(Src -> Count, Src -> Tags, NULL, NULL);
  684.     Ptail = Ptail -> Pnext;
  685.     PT_COPY(Ptail -> Pt, Src -> Pt);
  686.     PT_COPY(Ptail -> Normal, Src -> Normal);
  687.  
  688.     Src = Src -> Pnext;
  689.     }
  690.  
  691.     if (Src == SrcFirst) Ptail -> Pnext = Phead;/* Make vertex list circular.*/
  692.  
  693.     return Phead;
  694. }
  695.